package com.mangguo.tingjian.activity.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mangguo.tingjian.account.entity.User;
import com.mangguo.tingjian.activity.dto.*;
import com.mangguo.tingjian.activity.entity.DwChannelOpenApp;
import com.mangguo.tingjian.activity.entity.DwSubchannelResultApp;
import com.mangguo.tingjian.activity.mapper.DwChannelOpenAppMapper;
import com.mangguo.tingjian.activity.mapper.DwChannelResultAppMapper;
import com.mangguo.tingjian.activity.mapper.DwSubchannelResultAppMapper;
import com.mangguo.tingjian.activity.req.ActivityPageReq;
import com.mangguo.tingjian.activity.req.ActivityTrendReq;
import com.mangguo.tingjian.activity.req.ChannelPageReq;
import com.mangguo.tingjian.activity.req.ChannelTrendReq;
import com.mangguo.tingjian.activity.service.IDwChannelOpenAppService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mangguo.tingjian.common.ChannelOpenCommon;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.xml.crypto.Data;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author auto
 * @since 2019-11-25
 */
@Service("dwChannelOpenAppService")
@Slf4j
public class DwChannelOpenAppServiceImpl extends ServiceImpl<DwChannelOpenAppMapper, DwChannelOpenApp> implements IDwChannelOpenAppService {


    @Resource
    private DwChannelOpenAppMapper dwChannelOpenAppMapper;
    @Resource
    private DwSubchannelResultAppMapper dwSubchannelResultAppMapper;
    @Resource
    private DwChannelResultAppMapper dwChannelResultAppMapper;

    @Override
    public TodayActivityResult getTodayActivityData(String subChannelId){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        Integer today = Integer.valueOf(simpleDateFormat.format(new Date()));
        int todayActivateCount = dwChannelOpenAppMapper.selectActivityCountByDateAndType(today, subChannelId, ChannelOpenCommon.ProcessType.ACTIVATE.getCode());
        int todayRegistryCount = dwChannelOpenAppMapper.selectActivityCountByDateAndType(today, subChannelId, ChannelOpenCommon.ProcessType.REGISTRY.getCode());
        int totalActivateCount = dwChannelOpenAppMapper.selectActivityCountByTypeAndChannel(subChannelId, ChannelOpenCommon.ProcessType.ACTIVATE.getCode());
        int totalRegistryCount = dwChannelOpenAppMapper.selectActivityCountByTypeAndChannel(subChannelId, ChannelOpenCommon.ProcessType.REGISTRY.getCode());
        return TodayActivityResult.builder()
                .todayActivateCount(todayActivateCount)
                .todayRegistryCount(todayRegistryCount)
                .totalActivateCount(totalActivateCount)
                .totalRegistryCount(totalRegistryCount)
                .subChannelId(subChannelId)
                .build();
    }

    @Override
    public TodayChannelResult getTodayChannelData(String channelId){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        Integer today = Integer.valueOf(simpleDateFormat.format(new Date()));
        int todayActivateCount = dwChannelOpenAppMapper.selectChannelCountByDateAndType(today, channelId, ChannelOpenCommon.ProcessType.ACTIVATE.getCode());
        int todayRegistryCount = dwChannelOpenAppMapper.selectChannelCountByDateAndType(today, channelId, ChannelOpenCommon.ProcessType.REGISTRY.getCode());
        int totalActivateCount = dwChannelOpenAppMapper.selectChannelCountByTypeAndChannel(channelId, ChannelOpenCommon.ProcessType.ACTIVATE.getCode());
        int totalRegistryCount = dwChannelOpenAppMapper.selectChannelCountByTypeAndChannel(channelId, ChannelOpenCommon.ProcessType.REGISTRY.getCode());
        return TodayChannelResult.builder()
                .todayActivateCount(todayActivateCount)
                .todayRegistryCount(todayRegistryCount)
                .totalActivateCount(totalActivateCount)
                .totalRegistryCount(totalRegistryCount)
                .build();
    }

    @Override
    public List<ActivityTrendData> getActivityTrend(ActivityTrendReq req){

        List<TrendResult> activateResult = dwChannelOpenAppMapper.selectActivityCountByChannelAndTypeGroupByHour(req.getSubChannelId(), ChannelOpenCommon.ProcessType.ACTIVATE.getCode(), req.getMHourStart(), req.getMHourEnd());
        List<TrendResult> registryResult = dwChannelOpenAppMapper.selectActivityCountByChannelAndTypeGroupByHour(req.getSubChannelId(), ChannelOpenCommon.ProcessType.REGISTRY.getCode(), req.getMHourStart(), req.getMHourEnd());
        Map<Integer, TrendResult> activateResultMap = activateResult.stream().collect(Collectors.toMap(TrendResult :: getMNumberTime, activityTrendResult -> activityTrendResult));
        Map<Integer, TrendResult> registryResultMap = registryResult.stream().collect(Collectors.toMap(TrendResult :: getMNumberTime, activityTrendResult -> activityTrendResult));


        List<ActivityTrendData> activityTrendDataList  = Lists.newArrayList();
        //获得在此时间区间内，所有的小时数，并放入hourMap中
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHH");
        Calendar calendar = Calendar.getInstance();
        Date time = new Date();
        Date endTime = new Date();
        try {
            time = simpleDateFormat.parse(req.getMHourStart().toString());
            endTime = simpleDateFormat.parse(req.getMHourEnd().toString());
        }catch (Exception e){
            log.error("parse time error", e);
        }
        while (time.getTime() <= endTime.getTime()){
            Integer mNumTime = Integer.parseInt(simpleDateFormat.format(time));
            //每小时的趋势数据
            ActivityTrendData activityTrendData = ActivityTrendData.builder().build();
            if(activateResultMap.get(mNumTime) != null){
                activityTrendData.setActivateCount(activateResultMap.get(mNumTime).getCountNum());
            }else {
                activityTrendData.setActivateCount(0);
            }
            if(registryResultMap.get(mNumTime) != null){
                activityTrendData.setRegistryCount(registryResultMap.get(mNumTime).getCountNum());
            }else {
                activityTrendData.setRegistryCount(0);
            }
            activityTrendData.setTrendTime(mNumTime);
            activityTrendDataList.add(activityTrendData);
            calendar.setTime(time);
            calendar.add(Calendar.HOUR, 1);
            time = calendar.getTime();
        }
        return activityTrendDataList;
    }

    @Override
    public List<ChannelTrendData> getChannelTrend(ChannelTrendReq req){
        List<TrendResult> activateResult = dwChannelOpenAppMapper.selectChannelCountByChannelAndTypeGroupByHour(req.getChannelId(), ChannelOpenCommon.ProcessType.ACTIVATE.getCode(), req.getMHourStart(), req.getMHourEnd());
        List<TrendResult> registryResult = dwChannelOpenAppMapper.selectChannelCountByChannelAndTypeGroupByHour(req.getChannelId(), ChannelOpenCommon.ProcessType.REGISTRY.getCode(), req.getMHourStart(), req.getMHourEnd());
        Map<Integer, TrendResult> activateResultMap = activateResult.stream().collect(Collectors.toMap(TrendResult :: getMNumberTime, activityTrendResult -> activityTrendResult));
        Map<Integer, TrendResult> registryResultMap = registryResult.stream().collect(Collectors.toMap(TrendResult :: getMNumberTime, activityTrendResult -> activityTrendResult));


        List<ChannelTrendData> channelTrendDataList = Lists.newArrayList();
        //获得在此时间区间内，所有的小时数，并放入hourMap中
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHH");
        Calendar calendar = Calendar.getInstance();
        Date time = new Date();
        Date endTime = new Date();
        try {
            time = simpleDateFormat.parse(req.getMHourStart().toString());
            endTime = simpleDateFormat.parse(req.getMHourEnd().toString());
        }catch (Exception e){
            log.error("parse time error", e);
        }
        while (time.getTime() <= endTime.getTime()){
            Integer mNumTime = Integer.parseInt(simpleDateFormat.format(time));
            //每小时的趋势数据
            ChannelTrendData channelTrendData = ChannelTrendData.builder().build();
            if(activateResultMap.get(mNumTime) != null){
                channelTrendData.setActivateCount(activateResultMap.get(mNumTime).getCountNum());
            }else {
                channelTrendData.setActivateCount(0);
            }
            if(registryResultMap.get(mNumTime) != null){
                channelTrendData.setRegistryCount(registryResultMap.get(mNumTime).getCountNum());
            }else {
                channelTrendData.setRegistryCount(0);
            }
            channelTrendData.setTrendTime(mNumTime);
            calendar.setTime(time);
            calendar.add(Calendar.HOUR, 1);
            time = calendar.getTime();
        }
        return channelTrendDataList;
    }

    @Override
    public List<TodayActivityRankResult> getTodayActivityRankResult(Integer processType){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        Integer today = Integer.valueOf(simpleDateFormat.format(new Date()));
        List<TodayActivityRankResult> activityRankResults = dwChannelOpenAppMapper.selectActivityTodayActivityRank(today, processType);
        return activityRankResults;
    }

    @Override
    public List<TodayChannelRankResult> getChannelActivityRankResult(Integer processType){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        Integer today = Integer.valueOf(simpleDateFormat.format(new Date()));
        List<TodayChannelRankResult> channelRankResults = dwChannelOpenAppMapper.selectChannelTodayActivityRank(today, processType);
        return channelRankResults;
    }

    @Override
    public IPage<TodayActivityResult> getActivityPageResult(ActivityPageReq req){
        Page<DwSubchannelResultApp> page = new Page<>(req.getCurrent(), req.getSize(),true);
        IPage<DwSubchannelResultApp> dwSubchannelResultAppIPage =  dwSubchannelResultAppMapper.selectPage(page, new QueryWrapper<>());
        return dwSubchannelResultAppIPage.convert(dwSubchannelResultApp ->
             TodayActivityResult.builder()
                    .subChannelId(dwSubchannelResultApp.getSubchannelId())
                    .todayActivateCount(dwSubchannelResultApp.getTodayActivateCount())
                    .todayRegistryCount(dwSubchannelResultApp.getTodayRegistryCount())
                    .totalActivateCount(dwSubchannelResultApp.getTotalActivateCount())
                    .totalRegistryCount(dwSubchannelResultApp.getTotalRegistryCount())
                    .build()
        );
    }

    @Override
    public IPage<TodayChannelResult> getChannelPageResult(ChannelPageReq req){
        Page<TodayChannelResult> page = new Page<>(req.getCurrent(), req.getSize(),true);
        IPage<TodayChannelResult> todayChannelResultIPage = dwChannelResultAppMapper.selectChannelPageResult(page, req);
        return todayChannelResultIPage;
    }

}
